import java.awt.Graphics;
import java.util.*;

public class HexGrid{
	public static int radius = 40;
	
	public void paint(Graphics g) {
		double Yoffset = radius*Math.sin(Math.PI/3);
		double Xoffset = radius*Math.cos(Math.PI/3);
		int startx = (int)Xoffset;
		int starty = (int)Yoffset;
		for (int i = 0; i < dim[0]; i++) {
			for (int j = 0; j < dim[1]; j++) {
				for(int k = 0; k < dim[2]; k++){
					
				int y;
				if (j % 2 == 0)
					y = starty +(int)(i*2*Yoffset);
				else
					y = (int) (starty + Yoffset) + (int)(i*2*Yoffset);
				(grid[i][j][k]).setDrawMatrix((int) (startx + j * radius + j * Xoffset), y, radius);
				/*if(!grid[i][j][k].isEmpty()){  For Highlighting neighbors
					int [] tmp = {i,j,k};
					for (Hex h : get_neighbors(tmp)){
						h.drawHighlightHex(g);
					}
				}*/

				grid[i][j][k].drawHex(g);
					
				}
			}
		}
	}
	
	public void setAll(){
		for(int i = 0; i < dim[2]; i++){
			for(int j = 0; j < dim[0]; j++){
				for(int k = 0; k < dim[1]; k++){
					grid[j][k][i].setOccupant(this);
				}
			}
		}
	}
	 
	public void moveAll(){
		for(int i = 0; i < dim[2]; i++){
			for(int j = 0; j < dim[0]; j++){
				for(int k = 0; k < dim[1]; k++){
					grid[j][k][i].moveOccupant(this);
				}
			}
		}
		for(int i = 0; i < dim[2]; i++){
			for(int j = 0; j < dim[0]; j++){
				for(int k = 0; k < dim[1]; k++){
					grid[j][k][i].setOccupantMoved(false);
				}
			}
		}
		
	}
	
	/**
	 * Generates a random empty location in the hex grid and returns it in a 3 element array.
	 * The element order is row, col, depth.
	 * 
	 */
	public int[] RandomValidLocation()
	{
		int[] loc = new int[3];
		do{
		for(int i = 0; i < loc.length; i++)
			loc[i] = (int)(Math.random()*37) % dim[i];
		}while(!grid[loc[0]][loc[1]][loc[2]].isEmpty());
		
		return loc;
	}
	
	public void addToGridAt(Sprite toAdd,int r, int c, int d){
		grid[r][c][d].moveIntoHex(toAdd);
	}
	
	private Hex[][][] grid;
	private int[] dim;
	//defines the mapping of the grid onto the hex
	private int even_pattern[][] = {{0,0,1}, {0,0,-1}, 
							{1,0,0}, {-1,0,0}, 
							{0,1,0}, {0,-1,0}, 
							{-1,1,0}, {-1,-1,0}};
	private int odd_pattern[][] = {{0,0,1}, {0,0,-1}, 
							{-1,0,0}, {1,0,0}, 
							{0,-1,0}, {1,-1,0}, 
							{0,1,0}, {1,1,0}};
	//Create a hex grid of the given dimensions
	public HexGrid(int rows,int cols,int depth){
		grid = new Hex[rows][][];
		for(int r=0; r<rows; r++){
			grid[r] = new Hex[cols][];
			for(int c=0; c<cols; c++){
				grid[r][c] = new Hex[depth];
				for(int d=0; d<depth; d++){
					grid[r][c][d] = new Hex(r,c,d);
				}
			}
		}
		this.dim = new int[3];
		this.dim[0] = rows;
		this.dim[1] = cols;
		this.dim[2] = depth;
		
	}
	
	public Collection<Hex> get_neighbors(int[] location){
		Collection<Hex> neighbors = new ArrayList<Hex>();
		if(validLocation(location)){
			int pattern[][];
			if(location[1]%2 == 0)
				pattern = even_pattern;
			else
				pattern = odd_pattern;
			
			for(int r = 0; r<pattern.length; r++){
				int[] tmp = Arrays.copyOf(location,location.length);
				for(int c = 0; c<3; c++){
					tmp[c] += pattern[r][c];
				}
				if(validLocation(tmp)){
					neighbors.add(grid[tmp[0]][tmp[1]][tmp[2]]);
				}
			}
			return neighbors;
		}
		return neighbors;
	}
	
	public Collection<Hex> get_neighbors(Hex a){
		return this.get_neighbors(a.getLocation());
	}
	public final Hex get_hex(int[] location){
		return grid[location[0]][location[1]][location[2]];
	}

	
	public boolean validLocation(int[] location){
		if(location.length != 3)
			return false;
		
		boolean flag = true;
		for(int i=0; i<3; i++){
			flag &= location[i] >= 0 && location[i] < this.dim[i];
		}
		return flag;
		
	}

}
